package xyz.hubery.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import xyz.hubery.domain.User;
import xyz.hubery.domain.UserAuthAuditRecord;
import xyz.hubery.domain.UserAuthInfo;
import xyz.hubery.dto.UserDTO;
import xyz.hubery.feign.UserFeign;
import xyz.hubery.model.R;
import xyz.hubery.service.UserAuthAuditRecordService;
import xyz.hubery.service.UserAuthInfoService;
import xyz.hubery.service.UserService;
import xyz.hubery.vo.*;

import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping("/users")
@Api(tags = "会员的控制器")
public class UserController implements UserFeign {

    @Autowired
    private UserService userService;

    @Autowired
    private UserAuthInfoService userAuthInfoService;

    @Autowired
    private UserAuthAuditRecordService userAuthAuditRecordService;

    @PostMapping("/register")
    @ApiOperation("注册")
    public R<Boolean> register(@RequestBody @Validated RegisterForm registerForm) {
        boolean b = userService.register(registerForm);
        if(b){
            return R.ok();
        }
        return R.fail();
    }

    @GetMapping
    @ApiOperation(value = "查询会员的列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "会员的手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的 Id,精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实名称"),
            @ApiImplicitParam(name = "status", value = "会员的状态")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> findByPage(@ApiIgnore Page<User> page,
                                    String mobile,
                                    Long userId,
                                    String userName,
                                    String realName,
                                    Integer status
    ) {
        page.addOrder(OrderItem.desc("last_update_time"));
        Page<User> userPage =
                userService.page(page,
                        new LambdaQueryWrapper<User>()
                                .like(!StringUtils.isEmpty(mobile), User::getMobile, mobile)
                                .eq(userId != null, User::getId, userId)
                                .like(!StringUtils.isEmpty(userName), User::getUsername, userName)
                                .like(!StringUtils.isEmpty(realName), User::getRealName, realName)
                                .eq(status != null, User::getStatus, status)
                );
        return R.ok(userPage);
    }

    @PostMapping("/status")
    @ApiOperation(value = "修改用户的状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "会员的 id"),
            @ApiImplicitParam(name = "status", value = "会员的状态"),
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateStatus(Long id, Byte status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        boolean updateById = userService.updateById(user);
        if (updateById) {
            return R.ok("更新成功");
        }
        return R.fail("更新失败");
    }

    @PatchMapping
    @ApiOperation(value = "修改用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "会员的 json 数据"),
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateStatus(@RequestBody @Validated User user) {
        boolean updateById = userService.updateById(user);
        if (updateById) {
            return R.ok("更新成功");
        }
        return R.fail("更新失败");
    }


    @GetMapping("/info")
    @ApiOperation(value = "获取用户的详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的 Id")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<User> userInfo(Long id) {
        return R.ok(userService.getById(id));
    }


    @GetMapping("/directInvites")
    @ApiOperation(value = "查询该用户邀请的用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "该用户的 Id"),
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
    })
    public R<Page<User>> getDirectInvites(@ApiIgnore Page<User> page, Long userId) {
        Page<User> userPage = userService.page(page, new
                LambdaQueryWrapper<User>().eq(User::getDirectInviteid, userId));
        return R.ok(userPage);
    }


    @GetMapping("/auths")
    @ApiOperation(value = "用户审核列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "会员的手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的 Id,精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实名称"),
            @ApiImplicitParam(name = "reviewsStatus", value = "审核状态")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> findUserAuths(@ApiIgnore Page<User> page,
                                       String mobile,
                                       Long userId,
                                       String userName,
                                       String realName,
                                       Integer reviewsStatus
    ) {
        page.addOrder(OrderItem.desc("last_update_time"));
        Page<User> userPage =
                userService.page(page,
                        new LambdaQueryWrapper<User>()
                                .like(!StringUtils.isEmpty(mobile), User::getMobile, mobile)
                                .eq(userId != null, User::getId, userId)
                                .like(!StringUtils.isEmpty(userName), User::getUsername, userName)
                                .like(!StringUtils.isEmpty(realName), User::getRealName, realName)
                                .eq(reviewsStatus != null, User::getReviewsStatus, reviewsStatus)
                );
        return R.ok(userPage);
    }


    @GetMapping("/auth/info")
    @ApiOperation(value = "查询用户的认证详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的 Id")
    })
    public R<UseAuthInfoVo> getUseAuthInfo(Long id) {
        User user = null;
        List<UserAuthInfo> userAuthInfoList = null;
        List<UserAuthAuditRecord> userAuthAuditRecordList = null;
        // 1、查询用户信息
        user = userService.getById(id);
        // 2、根据用户id查询实名认证信息列表
        userAuthInfoList = userAuthInfoService.findByUserId(id);
        // 3、查询实名认证审核信息
        userAuthAuditRecordList = userAuthAuditRecordService.findByUserId(id);
        return R.ok(new UseAuthInfoVo(user, userAuthInfoList, userAuthAuditRecordList));
    }

    @PostMapping("/auths/status")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的 ID"),
            @ApiImplicitParam(name = "authStatus", value = "用户的审核状态"),
            @ApiImplicitParam(name = "authCode", value = "一组图片的唯一标识"),
            @ApiImplicitParam(name = "remark", value = "审核拒绝的原因"),
    })
    public R updateUserAuthStatus(@RequestParam(required = true) Long id, @RequestParam(required = true) Byte
            authStatus, @RequestParam(required = true) Long authCode, String remark) {
        // 审核: 1 修改 user 里面的 reviewStatus
             // 2 在 authAuditRecord 里面添加一条记录
        userService.updateUserAuthStatus(id, authStatus, authCode, remark);
        return R.ok();
    }


    @GetMapping("/current/info")
    @ApiOperation("获取当前用户信息")
    public R<User> getCurrentUserInfo() {
        String userIdStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userService.getById(Long.valueOf(userIdStr));
        user.setAccessKeyId("***");
        user.setAccessKeySecret("***");
        user.setPassword("***");
        user.setPaypassword("***");
        return R.ok(user);
    }


    @PostMapping("/authAccount")
    @ApiOperation("用户实名认证")
    public R authAccount(@RequestBody @Validated IdentifyForm identifyForm) {
        String userIdStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean b = userService.authAccount(Long.valueOf(userIdStr),identifyForm);
        if(b){
            return R.ok();
        }
        return R.fail("实名认证失败");
    }

    @PostMapping("/updatePhone")
    @ApiOperation("修改手机号")
    public R<Boolean> updatePhone(@RequestBody @Validated UpdatePhoneRequest phoneRequest) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean b = userService.checkPhoneAndCode(Long.valueOf(idStr),phoneRequest);
        if(b) { // 更新成功
            return R.ok();
        }
        return R.fail();
    }

    @GetMapping("/checkTel")
    @ApiOperation("检查手机号是否存在")
    public R<Boolean> checkTel(@RequestParam(value ="mobile",required = true ) String mobile,
                               @RequestParam(value ="countryCode",required = true ) String countryCode) {
       boolean b = userService.checkNewTelAndSend(mobile,countryCode);
       if(b){
           return R.ok();
       }
       return R.fail();
    }

    @PostMapping("/updateLoginPassword")
    @ApiOperation("修改登录密码")
    public R<Boolean> updateLoginPassword(@RequestBody @Validated UpdateLoginPasswordRequest passwordRequest) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean b = userService.updateLoginPassword(Long.valueOf(idStr),passwordRequest);
        if(b){
            return R.ok();
        }
        return R.fail();
    }

    @PostMapping("/setPayPassword")
    @ApiOperation("重置交易密码")
    public R<Boolean > setPayPassword(@RequestBody @Validated ResetPayPasswordRequest passwordRequest) {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean b = userService.setPayPassword(userId,passwordRequest);
        if(b){
            return R.ok();
        }
        return R.fail();
    }

    @PostMapping("/updatePayPassword")
    @ApiOperation("修改交易密码")
    public R<Boolean> updatePayPassword(@RequestBody @Validated UpdatePayPasswordRequest passwordRequest)  {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean b = userService.updatePayPassword(userId,passwordRequest);
        if(b){
            return R.ok();
        }
        return R.fail();
    }


    @GetMapping("/invites")
    @ApiOperation("邀请人员列表")
    public R<List<User>> invitesList() {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        List<User> userList= userService.invitesList(userId);
        return R.ok(userList);
    }

    @PostMapping("/setPassword")
    public R<Boolean> setPassword(@RequestBody @Validated SetPasswordRequest passwordRequest){
        boolean b = userService.setPassword(passwordRequest);
        if(b){
            return R.ok();
        }
        return R.fail();
    }

    /**
     * 获取用户的基础信息（用于远程调用）
     * @param ids
     * @return
     */
    @GetMapping("/basic/info")
    @Override
    public List<UserDTO> getBasicUserInfo(@RequestParam("ids") List<Long> ids) {
        return userService.getBasicUserInfo(ids);
    }



}
